package edu.hawaii.wattwaiter.page.gridinfo;

import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import org.apache.wicket.AttributeModifier;
import org.apache.wicket.Component;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.form.AjaxFormValidatingBehavior;
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
import org.apache.wicket.extensions.ajax.markup.html.AjaxLazyLoadPanel;
import org.apache.wicket.extensions.markup.html.tabs.TabbedPanel;
import org.apache.wicket.markup.html.WebComponent;
import org.apache.wicket.markup.html.form.CheckBox;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.AbstractReadOnlyModel;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.util.time.Duration;
import edu.hawaii.wattwaiter.page.WattWaiterSession;
import edu.hawaii.wattwaiter.wattdepotcommands.GoogleChartMaker;
import org.apache.wicket.extensions.yui.calendar.DatePicker;

/**
 * Displays Charts for Different Grids.
 * 
 * @author Remy
 * 
 */
public class GridInfo extends Panel {

  private static final long serialVersionUID = 1L;
  WattWaiterSession session = (WattWaiterSession) getSession();
  AjaxLazyLoadPanel image;
  AjaxLazyLoadPanel newImagePanel;

  /**
   * Source Get - gets grids.
   * 
   * @return list of sources
   * 
   */
  private List<String> populateSelect() {
    PopulateSources sources = new PopulateSources();

    List<String> sourceList = sources.getSources();
    Collections.sort(sourceList);
    return sourceList;
  }

  /**
   * Fills the form with Fields.
   * 
   * @param form empty
   * @return for filled
   */
  private Form<String> fillForm(Form<String> form) {
    // Date Fields - Beginning
    final TextField<Date> dateBegin =
        new TextField<Date>("beginningDate", new PropertyModel<Date>(session, "beginningDate"));
    dateBegin.add(new DatePicker());
    dateBegin.setRequired(true);
    form.add(dateBegin);
    session.setBeginningDate(dateBegin.getModelObject());
    System.out.println("Initial Start Date: " + session.getBeginningDate());

    // Date Fields - Ending
    final TextField<Date> endingDate =
        new TextField<Date>("endingDate", new PropertyModel<Date>(session, "endingDate"));
    endingDate.add(new DatePicker());
    endingDate.setRequired(true);
    form.add(endingDate);
    session.setEndingDate(endingDate.getModelObject());
    System.out.println("Initial End Date: " + session.getEndingDate());

    // Select for EnergyOrCarbon
    List<String> energyOrCarbonList = Arrays.asList("energy", "carbon");
    DropDownChoice<String> energyOrCarbonDrop =
        new DropDownChoice<String>("energyOrCarbon", new PropertyModel<String>(session,
            "energyOrCarbon"), energyOrCarbonList);
    energyOrCarbonDrop.setRequired(true);
    form.add(energyOrCarbonDrop);

    // Select for TimeFrame
    List<String> timeFrameList = Arrays.asList("week", "day", "hour");
    DropDownChoice<String> timeFrameDrop =
        new DropDownChoice<String>("timeFrame", new PropertyModel<String>(session, "timeFrame"),
            timeFrameList);
    timeFrameDrop.setRequired(true);
    form.add(timeFrameDrop);

    // Cumulative or Transitive boolean check box
    form.add(new CheckBox("transitive", new PropertyModel<Boolean>(session, "transitive")));
    form.add(new CheckBox("cumulative", new PropertyModel<Boolean>(session, "cumulative")));

    // Select for Locations
    List<String> locationsList = populateSelect();
    DropDownChoice<String> dropLocation =
        new DropDownChoice<String>("dropLocation", new PropertyModel<String>(session,
            "dropLocation"), locationsList);
    dropLocation.setRequired(true);
    form.add(dropLocation);

    return form;
  }

  /**
   * Grid info Constructor.
   * 
   */
  public GridInfo() {

    super(TabbedPanel.TAB_PANEL_ID);

    final FeedbackPanel feedback = new FeedbackPanel("feedback");
    feedback.setOutputMarkupId(true);
    add(feedback);

    // Begin Form
    Form<String> form = new Form<String>("Chart");
    form = fillForm(form);

    // Create Lazy Panel to hold the Image
    image = new AjaxLazyLoadPanel("image") {
      private static final long serialVersionUID = 1L;

      @Override
      public Component getLazyLoadComponent(String id) {
        session.setFirstVisit(true);
        return (new ChartPanel(id, session));

      }
    };
    add(image);

    // OnChange was clicked
    AjaxFormValidatingBehavior.addToAllFormComponents(form, "onchange", Duration.ONE_SECOND);

    // Add Ajax Behaviors
    form.add(new AjaxButton("ajax-button", form) {
      private static final long serialVersionUID = 1L;

      @Override
      protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
        // repaint the feedback panel so that it is hidden
        target.addComponent(feedback);

        newImagePanel = new AjaxLazyLoadPanel("image") {
          private static final long serialVersionUID = 1L;

          @Override
          public Component getLazyLoadComponent(String id) {
            session.setBeginningDate(session.getBeginningDate());
            session.setEndingDate(session.getEndingDate());
            session.setCumulative(session.getCumulative());
            session.setTransitive(session.getTransitive());
            session.setEnergyOrCarbon(session.getEnergyOrCarbon());
            session.setTimeFrame(session.getTimeFrame());
            session.setDropLocation(session.getDropLocation());
            return (new ChartPanel(id, session));
          }
        };
        newImagePanel.setOutputMarkupId(true);
        image.replaceWith(newImagePanel);
        image = newImagePanel;
        target.addComponent(newImagePanel, image.getMarkupId()); // igor says
      }

      @Override
      protected void onError(AjaxRequestTarget target, Form<?> form) {
        // repaint the feedback panel so errors are shown
        target.addComponent(feedback);
      }
    });
    add(form);

  }
}

/**
 * ChartPanel Class for assistance with LazyLoader.
 * 
 * @author Remy
 * 
 */
class ChartPanel extends Panel {

  private static final long serialVersionUID = 1L;
  private WattWaiterSession session = null;
  private Locale locale = Locale.US;
  private SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd", locale);

  /**
   * Constructor for ChartPanel.
   * 
   * @param id - id for panel
   * @param session - current session
   * 
   */
  public ChartPanel(String id, WattWaiterSession session) {
    super(id);
    this.session = session;
    addChart(this);
  }

  /**
   * Add Chart to Current Panel.
   * 
   * @param panel - panel to add chart to
   */
  public final void addChart(Panel panel) {
    WebComponent dynamicImage = new WebComponent("image");
    dynamicImage.add(new AttributeModifier("src", true, new AbstractReadOnlyModel<Object>() {
      private static final long serialVersionUID = 1L;

      /**
       * {@inheritDoc}
       */
      @Override
      public final Object getObject() {

        GoogleChartMaker chart =
            new GoogleChartMaker("http://server.wattdepot.org:8182/wattdepot/");

        String begDate = formatter.format(session.getBeginningDate());

        Date edate = session.getEndingDate();
        Calendar c = Calendar.getInstance();
        c.setTime(edate);
        c.add(Calendar.DATE, 1);
        String endDate = formatter.format(c.getTime());

        //System.out.println("End date2: " + endDate);
        // System.out.println("DEBUG: trans-" + session.getTransitive() + "  cum "
        // + session.getCumulative());
        if (session.getFirstVisit()) {
          session.setFirstVisit(false);
          // return "http://www2.hawaii.edu/~maud/chart.png";
          return chart.getChart("energy", begDate, endDate, "SIM_OAHU_GRID", "hour", false, false);
        }
        return chart.getChart(session.getEnergyOrCarbon(), begDate, endDate, session
            .getDropLocation(), session.getTimeFrame(), session.getTransitive(), session
            .getCumulative());

      }
    }));
    dynamicImage.setOutputMarkupId(true);
    panel.add(dynamicImage);
  }
}
